package com.yeban.factory.new_instance;

import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.util.function.Supplier;

/**
 * @Desc TODO
 * @Author yeban
 * @Date 2025/11/23
 */
public class NewInstances {

    public static void main(String[] args) {

        // 1、new对象
        Person p1 = new Person("张三");
        System.out.println("========== 1、new方法创建对象 ==========");
        System.out.println("p1 = " + p1);

        // 2、clone（Object中的clone方法，浅克隆）
        try {
            Person p2 = (Person) p1.clone();
            System.out.println("========== 2、clone浅克隆创建对象 ==========");
            System.out.println("p2 = " + p2);
        } catch (CloneNotSupportedException e) {
            throw new RuntimeException(e);
        }

        // 3、反射
        Class<? extends Person> clazz = p1.getClass();
        try {
            // 3.2 调用无参构造
            Person p3 = clazz.getDeclaredConstructor().newInstance();
            p3.setName("李四");
            System.out.println("========== 3、反射创建对象 ==========");
            System.out.println("无参构造： p3 = " + p3);

            // 3.3 调用有参构造
            Person p4 = clazz.getDeclaredConstructor(String.class).newInstance("王五");
            System.out.println("有参构造： p4 = " + p4);
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 4、序列化和反序列化
        try {
            // 序列化
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(bos);
            oos.writeObject(p1);

            // 反序列化
            ByteArrayInputStream bais = new ByteArrayInputStream(bos.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bais);
            Person p5 = (Person) ois.readObject();
            System.out.println("========== 4、反序列化（深克隆）创建对象 ==========");
            System.out.println("p5 = " + p5);
        } catch (IOException | ClassNotFoundException e) {
            throw new RuntimeException(e);
        }

        // 5、工厂（Factory）模式创建对象
        Fruit apple = FruitFactory.createFruit("apple");
        Fruit banana = FruitFactory.createFruit("banana");

        System.out.println("========== 5、工厂创建对象 ==========");
        System.out.println("创建apple对象：apple = " + apple);
        System.out.println("创建banana对象：banana = " + banana);

        // 6、函数式接口创建对象
        // 底层还是new，这是声明式的创建方式
        Supplier<Person> supplier = Person::new;
        Person p6 = supplier.get();
        p6.setName("赵六");
        System.out.println("========== 6、声明式创建对象 =========");
        System.out.println("p6 = " + p6);

        // 7、单例模式创建对象
        SingleInstance instance1 = SingleInstance.getInstance();
        SingleInstance instance2 = SingleInstance.getInstance();
        System.out.println("========== 7、单例创建对象 ==========");
        System.out.println("instance = " + instance1);
        System.out.println("instance = " + instance2);
    }
}
